package cc.rengu.redp.bizimpl.csmc.service.impl;
import cc.rengu.redp.bizimpl.csmc.dao.OrgDebitFeeReportMapper;
import cc.rengu.redp.bizimpl.csmc.domain.OrgCharge;
import cc.rengu.redp.bizimpl.csmc.domain.OrgDebitFee;
import cc.rengu.redp.bizimpl.csmc.service.ITOrgDebitFeeReportService;
import cc.rengu.redp.bizimpl.csmc.vo.OrgChargeVO;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.utils.SortUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
@Slf4j
public class OrgDebitFeeReportServiceImpl extends ServiceImpl<OrgDebitFeeReportMapper, OrgDebitFee> implements ITOrgDebitFeeReportService {

    //分页
    @Override
    public IPage<OrgDebitFee> findPage(QueryRequest request, OrgDebitFee orgDebitFee) {
        //分页
        Page<OrgDebitFee> page = new Page<>();

        //得到数据
        List<OrgDebitFee> debitFeeInfo = baseMapper.selectListC(orgDebitFee);
        List<OrgDebitFee> creditFeeInfo = baseMapper.selectListD(orgDebitFee);

        /*因为后面查的数据可能很大，这儿在法人行为空时直接返回空页*/
        if(StringUtils.isBlank(orgDebitFee.getInstId())){
            return page;
        }
        /*汇总*/
        List feeInfo = new ArrayList<>();
        /*以借方为基准逐个处理*/
        if(debitFeeInfo != null && debitFeeInfo.size()>0) {
            for (int i = 0; i < debitFeeInfo.size(); i++) {
                OrgDebitFee infoD = debitFeeInfo.get(i);
                for (int j = 0; creditFeeInfo!=null && j < creditFeeInfo.size(); j++) {
                    OrgDebitFee infoC = creditFeeInfo.get(j);
                    if (infoC.getInstId().equals(infoD.getInstId()) &&
                            infoC.getBatchDate().equals(infoD.getBatchDate()) &&
                            infoC.getAcqInstCode().equals(infoD.getAcqInstCode())) {
                        BigDecimal feeC = infoC.getActCupsFee();
                        BigDecimal feeD = infoD.getActCupsFee();
                        infoD.setActCupsFee(feeD.subtract(feeC).doubleValue());
                        /* 因为上面用group by查出来的肯定不会重复，这里每次处理完一个借方数据，就将贷方数据移除，并退出循环
                         * 一方面加快处理速度，另一方面方便判断贷方数据是否被汇总完毕
                         * 注意：如果不退出，移除元素后，会导致下一个元素取不到，直接取到下下个（虽然在现在的业务逻辑中不影响结果）*/
                        creditFeeInfo.remove(infoC);
                        break;
                    }
                }
                feeInfo.add(infoD);
            }
        }

        /*借方处理完毕，若还存在贷方数据，说明该机构手续费收入大于支出*/
        if(creditFeeInfo != null && creditFeeInfo.size() > 0){
            BigDecimal factor = new BigDecimal("-1");
            for (OrgDebitFee info : creditFeeInfo) {
                BigDecimal fee = info.getActCupsFee();
                info.setActCupsFee(fee.multiply(factor).doubleValue());
                feeInfo.add(info);
            }
        }

        /*排序: 法人行，批次日期（倒序），收单机构号*/
        sortResult(feeInfo);

        /*一定要保证feeInfo已经被实例化，否则需要判空*/
        Object count = feeInfo.size();

        //设置数据
        page.setRecords(feeInfo);
        //排序
        SortUtil.handlePageSort(request, page, true);
        return page;
    }

    //导出
    @Override
    public IPage<OrgDebitFee> findOrgDebitFeeReportDetail(QueryRequest request, OrgDebitFee orgDebitFee) {
        try {
            Page<OrgCharge> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            IPage<OrgDebitFee> pageOrgDebitFee =this.findPage(request, orgDebitFee);
            return pageOrgDebitFee;
        } catch (Exception e) {
            log.error("机构手续费支出报表失败", e);
            return null;
        }
    }

    /* 按照instId，batchDate 倒序，acqInstCode排序*/
    private void sortResult(List listOfMap){
        Collections.sort(listOfMap, new Comparator<OrgDebitFee>()
        {
            public int compare(OrgDebitFee o1, OrgDebitFee o2)
            {
                if(o1.getInstId().equals(o2.getInstId())){
                    if(o1.getBatchDate().equals(o2.getBatchDate())){
                        return String.valueOf(o1.getAcqInstCode()).compareTo(String.valueOf(o2.getAcqInstCode()));
                    } else {
                        /*批次日期倒序排列*/
                        return String.valueOf(o1.getBatchDate()).compareTo(String.valueOf(o2.getBatchDate())) * -1;
                    }
                } else {
                    return String.valueOf(o1.getInstId()).compareTo(String.valueOf(o2.getInstId()));
                }
            }
        });
    }
}
